package cool.houge.pig.infra.controller;

import am.ik.yavi.builder.ValidatorBuilder;
import am.ik.yavi.core.ConstraintViolationsException;
import am.ik.yavi.core.Validator;
import cool.houge.pig.AuthGrantType;
import cool.houge.pig.service.auth.AuthTokenInput;
import cool.houge.pig.service.auth.WeixinAuthService;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

/**
 * 微信小程序认证.
 *
 * @author KK (kzou227@qq.com)
 */
@Component
public class WeixinAuthController {

  private static final Validator<AuthTokenInput> XCX_INPUT_VALIDATOR =
      ValidatorBuilder.<AuthTokenInput>of()
          .constraint(AuthTokenInput::getClientId, "client_id", c -> c.notEmpty())
          .constraint(AuthTokenInput::getClientSecret, "client_secret", c -> c.notEmpty())
          .constraint(AuthTokenInput::getWeixinJsCode, "weixin_js_code", c -> c.notEmpty())
          .build();

  private final WeixinAuthService weixinAuthService;

  public WeixinAuthController(WeixinAuthService weixinAuthService) {
    this.weixinAuthService = weixinAuthService;
  }

  /**
   * 微信小程序认证.
   *
   * @param request 请求
   * @return 响应
   */
  public Mono<ServerResponse> xcxa(ServerRequest request) {
    return request
        .formData()
        .map(
            form ->
                AuthTokenInput.builder()
                    .grantType(AuthGrantType.HOUGE_WEIXIN_JS_CODE.getGrantType())
                    .clientId(form.getFirst("client_id"))
                    .clientSecret(form.getFirst("client_secret"))
                    .weixinJsCode(form.getFirst("weixin_js_code"))
                    .build())
        .doOnNext(
            input ->
                XCX_INPUT_VALIDATOR
                    .validate(input)
                    .throwIfInvalid(ConstraintViolationsException::new))
        .flatMap(weixinAuthService::xcx)
        .flatMap(ServerResponse.ok()::bodyValue);
  }
}
